//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//********************************************************* 

using System;
using System.Windows.Forms;
using Microsoft.TridentWordAddIn.Common;

namespace Microsoft.TridentWordAddIn.Presentation
{
    /// <summary>
    /// UIController class to manage task panes and ribbon UI from controller class
    /// </summary>
    public abstract class UIController
    {
        private readonly IUserControlCreator userControlCreator;
        private IRibbonInvalidator ribbonInvalidator;
        private ITaskPaneManager taskPaneManager;

        /// <summary>
        /// Initializes a new instance of the <see cref="UIController"/> class.
        /// </summary>
        /// <param name="userControlCreator">The user control creator.</param>
        protected UIController(IUserControlCreator userControlCreator)
        {
            this.userControlCreator = userControlCreator;
        }

        /// <summary>
        /// Gets or sets the task pane manager.
        /// </summary>
        /// <value>The task pane manager.</value>
        protected ITaskPaneManager TaskPaneManager
        {
            get
            {
                return this.taskPaneManager;
            }

            set
            {
                this.taskPaneManager = value;
                this.taskPaneManager.TaskPaneDockPositionChanged += new EventHandler<DockPositionChangedEventArgs>(taskPaneManager_TaskPaneDockPositionChanged);
                this.taskPaneManager.TaskPaneVisibilityChanged += new EventHandler<VisibilityChangedEventArgs>(taskPaneManager_TaskPaneVisibilityChanged);
            }
        }

        /// <summary>
        /// Gets or sets the ribbon invalidator.
        /// </summary>
        /// <value>The ribbon invalidator.</value>
        protected IRibbonInvalidator RibbonInvalidator
        {
            get
            {
                return this.ribbonInvalidator;
            }

            set
            {
                this.ribbonInvalidator = value;
            }
        }

        /// <summary>
        /// Initializes the base ribbon invalidator.
        /// </summary>
        /// <param name="invalidator">The invalidator.</param>
        public abstract void InitializeBaseRibbonInvalidator(IRibbonInvalidator invalidator);

        /// <summary>
        /// Initializes the base task pane manager.
        /// </summary>
        /// <param name="paneManager">The pane manager.</param>
        public abstract void InitializeBaseTaskPaneManager(ITaskPaneManager paneManager);

        /// <summary>
        /// Updates the ribbon.
        /// </summary>
        protected void UpdateRibbon()
        {
            this.ribbonInvalidator.Invalidate();
        }

        /// <summary>
        /// Shows the task pane.
        /// </summary>
        /// <param name="taskPaneKey">The task pane key.</param>
        /// <param name="isPressed">if set to <c>true</c> [is pressed].</param>
        /// <param name="documentKey">The document key.</param>
        protected void ShowCustomTaskPane(TaskPaneKey taskPaneKey, bool isPressed, int documentKey)
        {
            string title = this.userControlCreator.GetTaskPaneTitle(taskPaneKey);
            if (!this.taskPaneManager.TaskPaneExists(title, documentKey))
            {
                UserControl userControl =
                     this.userControlCreator.GetUserControl(taskPaneKey);
                this.taskPaneManager.CreateTaskPane(title, userControl);
            }

            this.taskPaneManager.SetTaskPaneVisibility(title, isPressed, documentKey);
        }

        /// <summary>
        /// Removes the task panes.
        /// </summary>
        protected void RemoveTaskPanes()
        {
            this.taskPaneManager.RemoveTaskPanes();            
        }

        /// <summary>
        /// Determines whether [is task pane visible] [the specified control id].
        /// </summary>
        /// <param name="controlId">The control id.</param>
        /// <param name="documentKey">The document key.</param>
        /// <returns>
        /// 	<c>true</c> if [is task pane visible] [the specified control id]; otherwise, <c>false</c>.
        /// </returns>
        protected bool IsTaskPaneVisible(string controlId, int documentKey)
        {
            TaskPaneKey taskPaneKey = this.userControlCreator.GetTaskPaneKey(controlId);
            string title = this.userControlCreator.GetTaskPaneTitle(taskPaneKey);
            return this.TaskPaneManager.IsTaskPaneVisible(title, documentKey);
        }

        /// <summary>
        /// Invalidates the control.
        /// </summary>
        /// <param name="controlKey">The control key.</param>
        protected void InvalidateControl(ControlKey controlKey)
        {
            string controlId = this.userControlCreator.GetRibbonControlId(controlKey);
            this.ribbonInvalidator.InvalidateControl(controlId);
        }

        /// <summary>
        /// Removes the pane.
        /// </summary>
        /// <param name="paneKey">The pane key.</param>
        protected void RemovePane(TaskPaneKey paneKey)
        {
            string title = this.userControlCreator.GetTaskPaneTitle(paneKey);
            this.taskPaneManager.RemoveTaskPane(title);
        }

        /// <summary>
        /// Handles the TaskPaneVisibilityChanged event of the taskPaneManager control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Microsoft.TridentWordAddIn.Common.VisibilityChangedEventArgs"/> instance containing the event data.</param>
        private void taskPaneManager_TaskPaneVisibilityChanged(object sender, VisibilityChangedEventArgs e)
        {
            TaskPaneKey taskPaneKey = this.userControlCreator.GetTaskPaneKey(e.TaskPaneTitle);
            if (this.ribbonInvalidator != null)
            {
                if (taskPaneKey != TaskPaneKey.EditWorkflow)
                {
                    this.ribbonInvalidator.InvalidateControl(this.userControlCreator.GetRibbonControlId(taskPaneKey));
                }
            }
        }

        /// <summary>
        /// Handles the TaskPaneDockPositionChanged event of the taskPaneManager control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Microsoft.TridentWordAddIn.Common.DockPositionChangedEventArgs"/> instance containing the event data.</param>
        private void taskPaneManager_TaskPaneDockPositionChanged(object sender, DockPositionChangedEventArgs e)
        {
            ITaskPaneControl control = this.taskPaneManager.GetTaskPaneUserControl(e.TaskPaneTitle, -1) as ITaskPaneControl;
            if (control != null)
            {
                control.SetDockPosition(e.DockPosition);
            }
        }
    }
}
